package com.jt.sys.service.realm;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.jt.common.annotation.RequestLog;
import com.jt.sys.dao.SysMenuDao;
import com.jt.sys.dao.SysRoleMenuDao;
import com.jt.sys.dao.SysUserDao;
import com.jt.sys.dao.SysUserRoleDao;
import com.jt.sys.entity.SysUser;
@Service
public class ShiroUserRealm extends AuthorizingRealm{
	@Autowired
	private SysUserDao sysUserDao;
	@Autowired
	private SysUserRoleDao sysUserRoleDao;
	@Autowired
	private SysRoleMenuDao sysRoleMenuDao;
	@Autowired
	private SysMenuDao sysMenuDao;
	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		HashedCredentialsMatcher cMatcher=new HashedCredentialsMatcher();
		cMatcher.setHashAlgorithmName("MD5");
		super.setCredentialsMatcher(cMatcher);
	}
	
 	/**
	 * 执行认证操作时此方法用于获取用户认证信息
	 * 此方法由认证管理器调用
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		//1.获取客户端提交的用户信息
		UsernamePasswordToken upToken=(UsernamePasswordToken) token;
		String username = upToken.getUsername();
//		char[] password = upToken.getPassword();
		//2.基于用户名从数据库查询用户信息
		SysUser user=sysUserDao.findUserByUserName(username);
		//3.校验用户信息(是否存在)
		if(user==null)
			throw new AuthenticationException();
		if(user.getValid()!=1){
			throw new AuthenticationException("jz");
		}
		//4.对用户信息进行封装
		ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt());
		SimpleAuthenticationInfo saInfo=new SimpleAuthenticationInfo(
				user, //principal:用户身份
				user.getPassword(), //hashedCredentials:已加密的密码
				credentialsSalt, //credentialsSalt:凭证,盐值
				this.getName());//realmName:realm name
		return saInfo;
	}
	
	/**
	 * 执行授权操作时此方法用于获取用户的权限信息
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//1.获取用户对象
		SysUser sysUser=(SysUser)principals.getPrimaryPrincipal();//依赖于doGetAuthenticationInfo方法中的用户身份,这里是user
		//2.基于用户Id查找角色Id
		List<Integer> list = sysUserRoleDao.findRoleIdsByUserId(sysUser.getId());
		Integer[] array = list.toArray(new Integer[]{});
		//3.基于用户角色Id查找菜单id
		List<Integer> list2 = sysRoleMenuDao.findMenuIdsByRoleId(array);
		Integer[] array2=list2.toArray(new Integer[]{});
		//4.基于菜单Id查找权限标识
		Set<String> pSet=new HashSet<>();
		List<String> permissions = sysMenuDao.findPermissions(array2);
		for (String permission : permissions) {
			if(!StringUtils.isEmpty(permission))
				pSet.add(permission);
		}//去重和空串儿
		SimpleAuthorizationInfo saIfo = new SimpleAuthorizationInfo();
		saIfo.setStringPermissions(pSet);
		System.out.println("打印权限"+saIfo);
		//5.封装权限信息到AuthorizationInfo
		return saIfo;
	}
	
}
